﻿var mapOptions = {
    credentials: "Anmx04OXCvmTobCwTZG1F8EWxQvfC-eodpfW1KKFb1PW48dW9uHS4r4t9_PPJfMl",
    mapTypeId: Microsoft.Maps.MapTypeId.road,
    zoom: 10,
    center: new Microsoft.Maps.Location(1.34, 103.68),
    width: 800,
    height: 400
}

var map = new Microsoft.Maps.Map(document.getElementById("mapDiv"), mapOptions);
Microsoft.Maps.Events.addHandler(map, 'rightclick', addPin);

var centerPin = null;
var creatingRadius = false;
var radiusPin = null;
var circle = null;
function addPin(e) {
    if (e.targetType == "map") {
        if (!creatingRadius) {
            if (centerPin != null) {
                map.entities.remove(centerPin);
            }
            var point = new Microsoft.Maps.Point(e.getX(), e.getY());
            var loc = e.target.tryPixelToLocation(point);
            document.getElementById("Center").value = loc.latitude + "," + loc.longitude;

            centerPin = new Microsoft.Maps.Pushpin(loc, { draggable: true });
            Microsoft.Maps.Events.addHandler(centerPin, 'mouseup', changeLatLongCenterPin);
            map.entities.push(centerPin);
        }
        else {
            
            if (radiusPin != null) {
                map.entities.remove(radiusPin);
            }
            var point = new Microsoft.Maps.Point(e.getX(), e.getY());
            var loc = e.target.tryPixelToLocation(point);
            

            radiusPin = new Microsoft.Maps.Pushpin(loc, { draggable: true });
            Microsoft.Maps.Events.addHandler(radiusPin, 'mouseup', changeRadius);
            map.entities.push(radiusPin);

            var radius = GetDistanceBetweenTwoPoints(centerPin.getLocation(), radiusPin.getLocation());
            if (circle != null)
                map.entities.remove(circle);
            circle = AddCircle(centerPin.getLocation(), radius);
            map.entities.push(circle);
            document.getElementById("Radius").value = radius;
        }
    }
}

function changeLatLongCenterPin(e) {
    if (e.targetType == "pushpin") {
        var pinLoc = e.target.getLocation();
        document.getElementById("Center").value = pinLoc.latitude + "," + pinLoc.longitude;
        if (radiusPin != null) {
            var radius = GetDistanceBetweenTwoPoints(centerPin.getLocation(), radiusPin.getLocation());
            if (circle != null)
                map.entities.remove(circle);
            circle = AddCircle(centerPin.getLocation(), radius);
            map.entities.push(circle);
            document.getElementById("Radius").value = radius;
        }
    }
}

function CreateRadius(credentials) {
    if (centerPin != null)
        creatingRadius = true;
}

function changeRadius(e)
{
    if (e.targetType == "pushpin") {
        var radius = GetDistanceBetweenTwoPoints(centerPin.getLocation(), radiusPin.getLocation());
        if (circle != null)
            map.entities.remove(circle);
        circle = AddCircle(centerPin.getLocation(), radius);
        map.entities.push(circle);
        document.getElementById("Radius").value = radius;
    }
}

function GetDistanceBetweenTwoPoints(p1, p2) {

    var distance = 0;

    var lat1 = p1.latitude;
    var lat2 = p2.latitude;

    var lon1 = p1.longitude;
    var lon2 = p2.longitude;

    var R = 6371; // km
    var dLat = (lat2 - lat1) * Math.PI / 180;
    var dLon = (lon2 - lon1) * Math.PI / 180;
    var lat1 = lat1 * Math.PI / 180;
    var lat2 = lat2 * Math.PI / 180;

    var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var d = R * c;

    //var dLat = (lat2 - lat1) / 180 * Math.PI;
    //var dLong = (long2 - long1) / 180 * Math.PI;
    //var a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
    //            + Math.cos(lat2) * Math.sin(dLong / 2) * Math.sin(dLong / 2);
    //var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    ////Calculate radius of earth
    //// For this you can assume any of the two points.
    //var radiusE = 637.8135; // Equatorial radius, in kmetres
    //var radiusP = 635.6750; // Polar Radius
    ////Numerator part of function
    //var nr = Math.pow(radiusE * radiusP * Math.cos(lat1 / 180 * Math.PI), 2);
    ////Denominator part of the function
    //var dr = Math.pow(radiusE * Math.cos(lat1 / 180 * Math.PI), 2)
    //                + Math.pow(radiusP * Math.sin(lat1 / 180 * Math.PI), 2);
    
    //var radius = Math.sqrt(nr) / Math.sqrt(dr);
    ////Calaculate distance in metres.
    //distance = radius * c;
    //if (isNaN(distance)) {
    //    alert(Math.sqrt(nr));
    //    alert(Math.sqrt(dr));
    //    alert(radius);
    //    alert(a);
    //}
    return d;
}

function AddCircle(latlong, radius) {

    var R = 6371; // earth's mean radius in km
    var lat = (latlong.latitude * Math.PI) / 180; //rad
    var lon = (latlong.longitude * Math.PI) / 180; //rad
    var d = parseFloat(radius) / R;  // d = angular distance covered on earth's surface
    var points = new Array();

    for (x = 0; x <= 360; x += 5){
        var p2 = new Microsoft.Maps.Location(0, 0);
        brng = x * Math.PI / 180;

        p2.latitude = Math.asin(Math.sin(lat) * Math.cos(d) + Math.cos(lat) * Math.sin(d) * Math.cos(brng));

        p2.longitude = ((lon + Math.atan2(Math.sin(brng) * Math.sin(d) * Math.cos(lat),
                         Math.cos(d) - Math.sin(lat) * Math.sin(p2.latitude))) * 180) / Math.PI;
        
        p2.latitude = (p2.latitude * 180) / Math.PI;
        points.push(p2);
    }

    var polygoncolor = new Microsoft.Maps.Color(100, 100, 0, 100);
    var poly = new Microsoft.Maps.Polygon(points, { fillColor: polygoncolor, strokeColor: polygoncolor });
    
    return poly;
}

// search function
function ClickGeocode(credentials) {
    map.getCredentials(MakeGeocodeRequest);
}

function MakeGeocodeRequest(credentials) {
    var geocodeRequest = "http://dev.virtualearth.net/REST/v1/Locations?query=" + encodeURI(document.getElementById('txtQuery').value) + "&output=json&jsonp=GeocodeCallback&key=" + credentials;
    CallRestService(geocodeRequest);
}

function CallRestService(request) {
    var script = document.createElement("script");
    script.setAttribute("type", "text/javascript");
    script.setAttribute("src", request);
    document.body.appendChild(script);
}

function GeocodeCallback(result) {
    
    if (result &&
           result.resourceSets &&
           result.resourceSets.length > 0 &&
           result.resourceSets[0].resources &&
           result.resourceSets[0].resources.length > 0) {
        // Set the map view using the returned bounding box
        
        var bbox = result.resourceSets[0].resources[0].bbox;
        var viewBoundaries = Microsoft.Maps.LocationRect.fromLocations(new Microsoft.Maps.Location(bbox[0], bbox[1]), new Microsoft.Maps.Location(bbox[2], bbox[3]));
        map.setView({ bounds: viewBoundaries });
        
        // Add a pushpin at the found location
        var resultLat = result.resourceSets[0].resources[0].point.coordinates[0];
        var resultLong = result.resourceSets[0].resources[0].point.coordinates[1];
        
        var location = new Microsoft.Maps.Location(resultLat, resultLong);
        //if (centerPin != null) {
        //    map.entities.remove(centerPin);
        //}
        if (centerPin != null)
            map.entities.remove(centerPin);
        centerPin = new Microsoft.Maps.Pushpin(location, { draggable: true });

        Microsoft.Maps.Events.addHandler(centerPin, 'mouseup', changeLatLongCenterPin);
        map.entities.push(centerPin);
        
        var input = document.getElementById("Center");
        input.value = resultLat + "," + resultLong;
    }
}